<!DOCTYPE html>
<html>
<head>
    <title>capture、self、once修饰符演示</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <style>
        .demo-container {
            margin: 20px 0;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .capture-demo .outer {
            padding: 40px;
            background: #ffeb3b;
            border: 2px solid #fbc02d;
        }
        .capture-demo .inner {
            padding: 20px;
            background: #4caf50;
            color: white;
            text-align: center;
        }
        .self-demo .container {
            padding: 40px;
            background: #e3f2fd;
            border: 2px solid #2196f3;
            text-align: center;
        }
        .self-demo .child {
            display: inline-block;
            padding: 20px;
            background: #ff5722;
            color: white;
            margin: 10px;
        }
        .once-demo {
            text-align: center;
        }
        .once-demo button {
            margin: 10px;
            padding: 10px 20px;
            font-size: 16px;
        }
        .log-panel {
            margin: 15px 0;
            padding: 10px;
            background: #f5f5f5;
            border: 1px solid #ddd;
            border-radius: 3px;
            max-height: 150px;
            overflow-y: auto;
        }
        .log-item {
            padding: 2px 0;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <div id="app">
        <h2>capture、self、once修饰符演示</h2>
        
        <!-- capture修饰符演示 -->
        <div class="demo-container">
            <h3>.capture修饰符 - 捕获阶段触发</h3>
            <p>说明：使用.capture的事件在捕获阶段就会触发，而不是等到冒泡阶段</p>
            
            <div class="capture-demo">
                <h4>普通事件（冒泡阶段）</h4>
                <div class="outer" @click="logCapture('外层-冒泡')">
                    外层div
                    <div class="inner" @click="logCapture('内层-冒泡')">
                        点击内层（冒泡顺序）
                    </div>
                </div>
                
                <h4>使用.capture（捕获阶段）</h4>
                <div class="outer" @click.capture="logCapture('外层-捕获')">
                    外层div
                    <div class="inner" @click="logCapture('内层-普通')">
                        点击内层（捕获优先）
                    </div>
                </div>
            </div>
            
            <div class="log-panel">
                <strong>Capture日志：</strong>
                <div v-for="log in captureLogs" :key="log.id" class="log-item">
                    {{ log.message }}
                </div>
                <button @click="captureLogs = []">清空</button>
            </div>
        </div>
        
        <!-- self修饰符演示 -->
        <div class="demo-container">
            <h3>.self修饰符 - 只在事件目标是自身时触发</h3>
            <p>说明：只有当event.target是当前元素自身时才触发，子元素触发的事件不会响应</p>
            
            <div class="self-demo">
                <h4>普通事件（会响应子元素）</h4>
                <div class="container" @click="logSelf('容器-普通')">
                    点击容器区域
                    <span class="child">子元素1</span>
                    <span class="child">子元素2</span>
                </div>
                
                <h4>使用.self（只响应自身）</h4>
                <div class="container" @click.self="logSelf('容器-self')">
                    点击容器区域（不包括子元素）
                    <span class="child">子元素1</span>
                    <span class="child">子元素2</span>
                </div>
            </div>
            
            <div class="log-panel">
                <strong>Self日志：</strong>
                <div v-for="log in selfLogs" :key="log.id" class="log-item">
                    {{ log.message }}
                </div>
                <button @click="selfLogs = []">清空</button>
            </div>
        </div>
        
        <!-- once修饰符演示 -->
        <div class="demo-container">
            <h3>.once修饰符 - 事件只触发一次</h3>
            <p>说明：事件处理函数只会执行一次，之后自动移除事件监听器</p>
            
            <div class="once-demo">
                <button @click="logOnce('普通按钮')">普通按钮（可多次点击）</button>
                <button @click.once="logOnce('一次性按钮')">一次性按钮（只能点击一次）</button>
                <button @click="resetOnceButton">重置一次性按钮</button>
            </div>
            
            <div class="log-panel">
                <strong>Once日志：</strong>
                <div v-for="log in onceLogs" :key="log.id" class="log-item">
                    {{ log.message }}
                </div>
                <button @click="onceLogs = []">清空</button>
            </div>
        </div>
    </div>

    <script>
        const { createApp, ref } = Vue;
        
        createApp({
            setup() {
                const captureLogs = ref([]);
                const selfLogs = ref([]);
                const onceLogs = ref([]);
                let logId = 1;
                
                const logCapture = (message) => {
                    captureLogs.value.push({
                        id: logId++,
                        message: `${new Date().toLocaleTimeString()} - ${message}`
                    });
                };
                
                const logSelf = (message) => {
                    selfLogs.value.push({
                        id: logId++,
                        message: `${new Date().toLocaleTimeString()} - ${message}`
                    });
                };
                
                const logOnce = (message) => {
                    onceLogs.value.push({
                        id: logId++,
                        message: `${new Date().toLocaleTimeString()} - ${message} 被点击`
                    });
                };
                
                const resetOnceButton = () => {
                    // 注意：Vue的.once修饰符无法通过JavaScript重置
                    // 这里只是演示概念，实际应用中需要重新渲染组件
                    onceLogs.value.push({
                        id: logId++,
                        message: `${new Date().toLocaleTimeString()} - 提示：.once修饰符无法重置，需要重新渲染组件`
                    });
                };
                
                return {
                    captureLogs,
                    selfLogs,
                    onceLogs,
                    logCapture,
                    logSelf,
                    logOnce,
                    resetOnceButton
                };
            }
        }).mount('#app');
    </script>
</body>
</html>
